﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Infrastructure;
using Microsoft.Practices.Unity;
using Microsoft.Practices.Prism.Events;
using Microsoft.Practices.Prism.Regions;
using System.Collections.ObjectModel;
using DBDataAccessLib;
using DBDataAccessLib.DataMapping;
using PluginManager;
using Microsoft.Practices.Prism.Commands;
using Telerik.Windows.Controls;
using System.Windows;
using Infrastructure.Events;

namespace UserPermission.ViewModel
{
    public class UserPermissionViewModel : Infrastructure.ViewModelBase
    {
        public UserPermissionViewModel(IUnityContainer container, IEventAggregator eventAggregator, IRegionManager regionMgr)
            : base(container, eventAggregator)
        {
            ComboBoxLostFocus = new DelegateCommand<object>(OnComboBoxLostFocus);
            SaveCommand = new DelegateCommand<object>(OnSaveCommandClick, OnCanSaveCommandClick);
            DeleteClick = new DelegateCommand<object>(OnDeleteClick, OnCanDeleteClick);
            GetAllAccounts();
            SetCurrentUserSelectedIndex();
        }

        public DelegateCommand<object> ComboBoxLostFocus { get; set; }
        public DelegateCommand<object> SaveCommand { get; set; }
        public DelegateCommand<object> DeleteClick { get; set; }

        public void OnSaveCommandClick(object btn)
        {
            int permission = 0;
            //permission
            if (CanManageInfo) permission += (int)Permission.ManageInfo;
            if (CanManageSysParam) permission += (int)Permission.ManageSysParam;
            if (CanManageUser) permission += (int)Permission.ManageUser;
            if (CanPlayInfo) permission += (int)Permission.PlayInfo;
            if (CanUploadImages) permission += (int)Permission.UploadImages;
            if (CanUploadInfo) permission += (int)Permission.UploadInfo;
            if (CanManageImages) permission += (int)Permission.ManageImages;
            string function = permission.ToString();

            if (password != confirmedPassword)
            {
                ModalWindowService.ShowMessage("密码与重复密码不一致。", null);
                return;
            }
            AccountMapping mapping = UserNames.FirstOrDefault(p => p.UserName == UserName);
            if (mapping != null)//update
            {
                ModalWindowService.ShowConfirmMessage("确定要更新" + UserName + "的记录吗？", result =>
                {
                    if (MessageBoxResult.Yes == result)
                    {
                        int isSuccess = UserDataAccess.UpdateUser(UserName, password, function);
                        if (isSuccess == 1)
                        {
                            GetAllAccounts();
                            SelectedUserName = UserNames.FirstOrDefault(p => p.UserName == UserName);
                            if ((GeneralInformation.ViewStates["UserInfo"] as AccountMapping).UserName == UserName)
                            {
                                GeneralInformation.ViewStates["UserInfo"] = SelectedUserName;
                                EventAggregator.GetEvent<OnSwitchUserEvent>().Publish(null);
                            }
                            ModalWindowService.ShowMessage("更新成功", null);
                        }
                        else ModalWindowService.ShowMessage("更新失败，请稍候再试", null);
                    }
                });
            }
            else//insert
            {
                ModalWindowService.ShowConfirmMessage("确定要新增" + UserName + "的记录吗？", result =>
                {
                    if (MessageBoxResult.Yes == result)
                    {
                        int isSuccess = UserDataAccess.AddUser(UserName, password, function);
                        if (isSuccess == 1)
                        {
                            GetAllAccounts();
                            SelectedUserName = UserNames.FirstOrDefault(p => p.UserName == UserName);
                            ModalWindowService.ShowMessage("新增成功", null);
                        }
                        else ModalWindowService.ShowMessage("新增失败，请稍候再试", null);
                    }
                });
            }
            RaiseButtonsCanExecuteChanged();
        }

        public bool OnCanSaveCommandClick(object obj)
        {
            return !string.IsNullOrEmpty(UserName) && !string.IsNullOrEmpty(Password) && !string.IsNullOrEmpty(ConfirmedPassword);
        }

        public void OnDeleteClick(object btn)
        {
            if (UserName.ToLower() == "admin")
            {
                MessageBox.Show("Admin不允许被删除。");
                return;
            }
            ModalWindowService.ShowConfirmMessage("确定要删除" + UserName + "吗？", result =>
            {
                if (MessageBoxResult.Yes == result)
                {
                    int isSuccess = UserDataAccess.DeleteUser(UserName);
                    if (isSuccess == 1)
                    {
                        GetAllAccounts();
                        SelectedUserName = UserNames.First();
                        UserName = SelectedUserName.UserName;
                        OnComboBoxLostFocus(null);
                        MessageBox.Show("删除成功");
                    }
                    else MessageBox.Show("删除失败，请稍候再试");
                }
            });
        }

        public bool OnCanDeleteClick(object obj)
        {
            AccountMapping account = GeneralInformation.ViewStates["UserInfo"] as AccountMapping;
            bool canManageUser = (int.Parse(account.Function) & (int)Permission.ManageUser) != 0;
            AccountMapping mapping = null;
            if (UserNames != null) mapping = UserNames.FirstOrDefault(p => p.UserName == UserName);
            return canManageUser && UserName != account.UserName && (mapping != null);
        }

        private void SetCurrentUserSelectedIndex()
        {
            AccountMapping account = UserNames.FirstOrDefault(p => p.UserName ==
                (GeneralInformation.ViewStates["UserInfo"] as AccountMapping).UserName);
            if (account != null)
            {
                this.SelectedUserName = account;
                this.UserName = account.UserName;
                OnComboBoxLostFocus(null);
            }
        }

        private void GetAllAccounts()
        {
            UserNames = UserDataAccess.GetAllAccounts().ToObservableCollection();
        }

        private ObservableCollection<AccountMapping> userNames;

        public ObservableCollection<AccountMapping> UserNames
        {
            get { return userNames; }
            set
            {
                userNames = value;
                OnPropertyChanged("UserNames");
            }
        }

        private AccountMapping selectedUserName;

        public AccountMapping SelectedUserName
        {
            get { return selectedUserName; }
            set
            {
                if (value != null)
                {
                    selectedUserName = value;
                    OnPropertyChanged("SelectedUserName");
                }
            }
        }

        private string password;

        public string Password
        {
            get { return password; }
            set
            {
                password = string.IsNullOrWhiteSpace(value) ? value : value.Trim();
                RaiseButtonsCanExecuteChanged();
                OnPropertyChanged("Password");
            }
        }

        private string confirmedPassword;

        public string ConfirmedPassword
        {
            get { return confirmedPassword; }
            set
            {
                confirmedPassword = string.IsNullOrWhiteSpace(value) ? value : value.Trim();
                RaiseButtonsCanExecuteChanged();
                OnPropertyChanged("ConfirmedPassword");
            }
        }

        private bool canUploadImages;

        public bool CanUploadImages
        {
            get { return canUploadImages; }
            set
            {
                canUploadImages = value;
                OnPropertyChanged("CanUploadImages");
            }
        }

        private bool canManageImages;

        public bool CanManageImages
        {
            get { return canManageImages; }
            set
            {
                canManageImages = value;
                OnPropertyChanged("CanManageImages");
            }
        }


        private bool canUploadInfo;

        public bool CanUploadInfo
        {
            get { return canUploadInfo; }
            set
            {
                canUploadInfo = value;
                OnPropertyChanged("CanUploadInfo");
            }
        }

        private bool canManageInfo;

        public bool CanManageInfo
        {
            get { return canManageInfo; }
            set
            {
                canManageInfo = value;
                OnPropertyChanged("CanManageInfo");
            }
        }

        private bool canPlayInfo;

        public bool CanPlayInfo
        {
            get { return canPlayInfo; }
            set
            {
                canPlayInfo = value;
                OnPropertyChanged("CanPlayInfo");
            }
        }

        private bool canManageUser;

        public bool CanManageUser
        {
            get { return canManageUser; }
            set
            {
                canManageUser = value;
                OnPropertyChanged("CanManageUser");
            }
        }

        private bool canManageSysParam;

        public bool CanManageSysParam
        {
            get { return canManageSysParam; }
            set
            {
                canManageSysParam = value;
                OnPropertyChanged("CanManageSysParam");
            }
        }

        public string UserName { get; set; }

        public void OnComboBoxLostFocus(object obj)
        {
            RadComboBox combo = obj as RadComboBox;
            if (combo != null) UserName = combo.Text;
            AccountMapping account = UserNames.FirstOrDefault(p => p.UserName == UserName);
            ResetPassword(UserName == SelectedUserName.UserName);
            ResetPermissions();
            if (account != null)
            {
                int permission = int.Parse(account.Function);
                if ((permission & (int)Permission.ManageInfo) != 0) CanManageInfo = true;
                if ((permission & (int)Permission.ManageSysParam) != 0) CanManageSysParam = true;
                if ((permission & (int)Permission.ManageUser) != 0) CanManageUser = true;
                if ((permission & (int)Permission.PlayInfo) != 0) CanPlayInfo = true;
                if ((permission & (int)Permission.UploadImages) != 0) CanUploadImages = true;
                if ((permission & (int)Permission.UploadInfo) != 0) CanUploadInfo = true;
                if ((permission & (int)Permission.ManageImages) != 0) CanManageImages = true;

                Password = account.Password;
                ConfirmedPassword = account.Password;
            }
            RaiseButtonsCanExecuteChanged();
        }

        private void RaiseButtonsCanExecuteChanged()
        {
            SaveCommand.RaiseCanExecuteChanged();
            DeleteClick.RaiseCanExecuteChanged();
        }

        private void ResetPermissions()
        {
            CanManageInfo = false;
            CanManageSysParam = false;
            CanManageUser = false;
            CanPlayInfo = false;
            CanUploadImages = false;
            CanUploadInfo = false;
            CanManageImages = false;
        }

        private void ResetPassword(bool isRecoveryPasswords)
        {
            if (isRecoveryPasswords)
            {
                Password = Password;
                ConfirmedPassword = Password;
            }
            else
            {
                Password = string.Empty;
                ConfirmedPassword = string.Empty;
            }
        }
    }
}
